package com.info.provider.aspect;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * Created by pengshuo on 2017/9/15 9:16.
 * Description:
 * Modified By:
 * Version:
 *
 * @author pengshuo
s */
@Aspect
@Order(7)
@Component
public class LogAspect {

    Logger logger = LogManager.getLogger(this.getClass());

    /** startTime */
    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Pointcut("execution(public * com.info.provider.web..*.*(..))")
    public void logger(){}

    /**
     * 切入点之前运行的方法
     * @param joinPoint
     * @throws Throwable
     */
    @Before("logger()")
    public void doBefore(JoinPoint joinPoint) throws Throwable{
        startTime.set(System.currentTimeMillis());
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        logger.info("url:   " + request.getRequestURI().toString());
        logger.info("http_method:   " + request.getMethod());
        logger.info("ip:    " + request.getRemoteAddr());
        logger.info("class_method:  " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        logger.info("args:   " + Arrays.toString(joinPoint.getArgs()));
    }

    /**
     * 切入点return内容之后切入内容,对返回值进行处理
     * @param object
     */
    @AfterReturning(pointcut = "logger()",returning = "object")
    public void doAfterReturning(Object object) throws Throwable{
        // 处理完请求，对返回内容进行记录
        logger.info("return:   " + object);
        logger.info("spend_time:    " + (System.currentTimeMillis() - startTime.get()) + " 毫秒");
    }

}
